import 'dart:convert';
import 'package:connectivity/connectivity.dart';
import 'package:dio/dio.dart';
import 'package:flutter_douban/network/http_data.dart';

import 'http_code.dart';

class Config {
  static const bool DEBUG = true;
}

class JsonUtil {
  static JsonEncoder encoder = JsonEncoder.withIndent('    ');
  static void printJson(Object object) {
    try {
      var encoderString = encoder.convert(object);
      // 输出json 不全
      print("\n" + encoderString + "\n");
      // 输出全json
      //debugPrint(encoderString);
    } catch (e) {
      print(e);
    }
  }
}

// 请求发送包装token 或其他操作拦截器
class TokenInterceptors extends InterceptorsWrapper {
  String _token;

  @override
  Future onRequest(RequestOptions options) async {
    //TODO 获取缓存全局token
    if (_token != null) {
      options.headers["token"] = _token;
    }
    return super.onRequest(options);
  }
}

// 检测网络拦截器
class ErrorInterceptors extends InterceptorsWrapper {
  final Dio _dio;
  ErrorInterceptors(this._dio);

  @override
  Future onRequest(RequestOptions options) async {
    // 检测网络
    var connectivityResult = await Connectivity().checkConnectivity();
    if (connectivityResult == ConnectivityResult.none) {
      return _dio.resolve(HttpData(
          false,
          HttpCode.errorHandle(HttpCode.NETWORK_ERROR, ""),
          HttpCode.NETWORK_ERROR));
    }
    return super.onRequest(options);
  }
}

// 日志打印拦截器 缓存最近20个请求数据
class LogInterceptors extends InterceptorsWrapper {
  static List<String> requstUrls = <String>[];
  static List<Map<String, dynamic>> requsts = <Map<String, dynamic>>[];

  static List<String> responseUrls = <String>[];
  static List<Map<String, dynamic>> responses = <Map<String, dynamic>>[];

  static List<String> errorUrls = <String>[];
  static List<Map<String, dynamic>> errors = <Map<String, dynamic>>[];

  @override
  Future onRequest(RequestOptions options) async {
    if (Config.DEBUG) {
      var debugData = Map<String, dynamic>();
      debugData["requestUrl"] = options.uri.toString();
      debugData["requestMethod"] = options.method;
      debugData["requestData"] = options.data ?? "";
      debugData["requestHeader"] = options.headers ?? "";
      print("=============request start=============");
      JsonUtil.printJson(debugData);
    }
    try {
      var data;
      addLogic(requstUrls, options.path ?? "");
      if (options.data is Map) {
        data = options.data;
      } else {
        data = Map<String, dynamic>();
      }
      var map = {
        "header": {...options.headers},
      };
      if (options.method == "POST") {
        map["data"] = data;
      }
      addLogic(requsts, map);
    } catch (e) {
      print(e);
    }

    return super.onRequest(options);
  }

  @override
  Future onResponse(Response response) async {
    if (Config.DEBUG) {
      print("=============request data=============");
      JsonUtil.printJson(response.data);
      print("=============request end==============");
    }
    if (response.data != null) {
      try {
        var data = Map<String, dynamic>();
        data["data"] = response.data;
        addLogic(responseUrls, response.request.uri.toString() ?? "");
        addLogic(responses, data);
      } catch (e) {
        print(e);
      }
    }
    return super.onResponse(response);
  }

  @override
  Future onError(DioError err) async {
    if (Config.DEBUG) {
      print("=============request error=============");
      JsonUtil.printJson(err.toString());
      print("=============request end===============");
    }
    try {
      var data = Map<String, dynamic>();
      data["error"] = err.toString();
      addLogic(errorUrls, err.request.uri.toString() ?? "");
      addLogic(errors, data);
    } catch (e) {
      print(e);
    }
    return super.onError(err);
  }

  static addLogic(List list, data) {
    if (list.length > 20) {
      list.removeAt(0);
    }
    list.add(data);
  }
}

// 请求成功data转换拦截器
class ResponseInterceptors extends InterceptorsWrapper {
  @override
  Future onResponse(Response response) async {
    RequestOptions options = response.request;
    var value;
    try {
      var header = response.headers[Headers.contentTypeHeader];
      if (header != null && header.toString().contains("text")) {
        value = HttpData(response.data, true, HttpCode.SUCCESS);
      } else if (response.statusCode >= 200 && response.statusCode <= 300) {
        value = HttpData(response.data, true, HttpCode.SUCCESS,
            headers: response.headers);
      }
    } catch (e) {
      print(e.toString() + options.path);
      value = HttpData(e.toString(), false, response.statusCode,
          headers: response.headers);
    }
    if (value != null) {
      response.data = value;
    }
    return super.onResponse(response);
  }
}
